package com.huawei.boss.ibatis;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.apache.commons.io.IOUtils;
import org.apache.log4j.Logger;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.xml.sax.EntityResolver;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

public final class SqlMapConfigUtils {
    private static final Logger LOGGER = Logger.getLogger(SqlMapConfigUtils.class);

    /**
     * 读取sqlmap配置文件
     */
    public static List<FileDesc> readSqlMapFileMapping(String sqlMapConfig) {
        InputStreamReader isr = null;
        try {
            File f = new File(sqlMapConfig);
            isr = new InputStreamReader(new FileInputStream(f), "utf-8");

            SAXReader builder = new SAXReader();
            //不进行 DTD 验证
            builder.setEntityResolver(new EntityResolver() {
                @Override
                public InputSource resolveEntity(String publicId, String systemId) throws SAXException, IOException {
                    return new InputSource(new ByteArrayInputStream("".getBytes("UTF-8")));
                }
            });

            Document doc = builder.read(isr);
            Element root = doc.getRootElement();
            List<?> list = root.elements("sqlMap");
            List<FileDesc> retList = new ArrayList<FileDesc>();
            for (Iterator<?> it = list.listIterator(); it.hasNext();) {
                Element e = (Element) it.next();
                String loc = e.attributeValue("resource");
                URL url = Thread.currentThread().getContextClassLoader().getResource(loc);
                File file = new File(url.getFile());
                long lastTm = file.lastModified();
                FileDesc fd = new FileDesc(file.getAbsolutePath(), lastTm);
                retList.add(fd);
            }
            return retList;
        } catch (Exception e) {
            LOGGER.error(e);
        } finally {
            IOUtils.closeQuietly(isr);
        }

        return new ArrayList<FileDesc>();
    }

    /**
     * 读取配置文件, 获取sql列表
     */
    public static List<String> readSqlMap(FileDesc fd) {
        InputStreamReader isr = null;
        try {
            String path = fd.getPath();
            isr = new InputStreamReader(new FileInputStream(path), "utf-8");
            SAXReader builder = new SAXReader();
            builder.setEntityResolver(new EntityResolver() {
                @Override
                public InputSource resolveEntity(String publicId, String systemId) throws SAXException, IOException {
                    return new InputSource(new ByteArrayInputStream("".getBytes("UTF-8")));
                }
            }); // 不进行 DTD 验证
            Document doc = builder.read(isr);
            Element root = doc.getRootElement();
            String namespace = null;
            if (root.attribute("namespace") != null) {
                namespace = root.attributeValue("namespace");
            }
            List<?> list = root.elements();
            List<String> retList = new ArrayList<String>();
            for (Iterator<?> it = list.listIterator(); it.hasNext();) {
                Element e = (Element) it.next();
                String tagName = e.getName();
                if ("statement".equals(tagName) || "insert".equals(tagName) || "update".equals(tagName)
                        || "delete".equals(tagName) || "select".equals(tagName) || "procedure".equals(tagName)) {
                    String id = e.attributeValue("id");
                    if (namespace != null) {
                        id = namespace + "." + id;
                    }
                    retList.add(id);
                }
            }
            return retList;
        } catch (UnsupportedEncodingException e) {
            LOGGER.error(e);
        } catch (IOException e) {
            LOGGER.error(e);
        } catch (DocumentException e) {
            LOGGER.error(e);
        } finally {
            IOUtils.closeQuietly(isr);
        }

        return new ArrayList<String>();
    }
}
